using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace QXFramework.Net
{
    public class ByteArray
    {
        private byte[] bytes;
        private const int defaultCapacity = 1024;

        public byte[] Bytes
        {
            get { return bytes; }
        }

        private int readIndex;
        public int ReadIndex
        {
            get { return readIndex; }
            private set { readIndex = value; }
        }

        private int writeIndex;
        public int WriteIndex
        {
            get { return writeIndex; }
            private set { writeIndex = value; }
        }

        private int capacity;
        public int Capacity
        {
            get { return capacity; }
            private set
            {
                if (value < 0)
                {
                    throw new ArgumentException("Capacity can not be negative.");
                }
                if (value < bytes.Length)
                {
                    throw new ArgumentException("Capacity can not be smaller than current length.");
                }
                if (value > defaultCapacity)
                {
                    capacity = value;
                    byte[] newBytes = new byte[capacity];
                    Array.Copy(bytes, 0, newBytes, 0, bytes.Length);
                    bytes = newBytes;
                }
            }
        }

        public int DataLength
        {
            get { return writeIndex - readIndex; }
        }

        public int RemainLength
        {
            get { return bytes.Length - writeIndex; }
        }

        public ByteArray(int capacity = defaultCapacity)
        {
            bytes = new byte[capacity];
            this.capacity = capacity;
            readIndex = 0;
            writeIndex = 0;
        }

        public ByteArray(byte[] bytes)
        {
            this.bytes = bytes;
            capacity = bytes.Length;
            readIndex = 0;
            writeIndex = bytes.Length;
        }

        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="count"></param>
        public void PushBytes(int count)
        {
            WriteIndex += count;
            //当容量不足时，扩容
            if (WriteIndex > Capacity || RemainLength < 8)
            {
                ExpandCapacity(Capacity * 2);
            }
        }

        /// <summary>
        /// 移除数据
        /// </summary>
        /// <param name="count"></param>
        public bool PopBytes(int count)
        {
            if (count > DataLength) return false;
            ReadIndex += count;
            //当数据长度为0时，清空数组
            if (ReadIndex == WriteIndex)
            {
                ReadIndex = 0;
                WriteIndex = 0;
                return true;
            }
            //当数据长度不为0时，将数据移动到数组头部
            if (DataLength > 0)
            {
                Array.Copy(bytes, ReadIndex, bytes, 0, DataLength);
                WriteIndex = DataLength;
                ReadIndex = 0;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 扩容
        /// </summary>
        /// <param name="size">扩容大小</param>
        public void ExpandCapacity(int size)
        {
            if (size > Capacity)
            {
                int newCapacity = Capacity * 2;
                if (newCapacity < defaultCapacity)
                {
                    newCapacity = defaultCapacity;
                }
                if (newCapacity < size)
                {
                    newCapacity = size;
                }
                Capacity = newCapacity;
            }
        }
    }
}